/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Servidor;
import Cliente.Partida;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Esta clase se crea en lado del servidor y administra las partidas creadas en
 * el sistema.
 * Contiene una lista de partidas cuyo rango va de 0 a 50.
 * Contiene una lista de clientes que se han conectado al sistema puede ir de 0
 * a 200 conexiones.
 */
public class AdminPartidas {
        ArrayList<Partida> partidas=new ArrayList<Partida>();
        ArrayList<ServidorThread> clientes=new ArrayList<ServidorThread>();
	int usuarios=0;

        /**
         * Este metodo permite conocer cuantas partidas hay en el sistema.
         * Precondición:
         * Postcondición: Número de partidas creadas en el sistema.
         * @return int
         * este parametro indica la cantidad de partidas que se han creado en
         * el juego.
         * Rango: desde 0 hasta 50 partidas para este caso concreto.
         */
        public int getPartidas(){
            return this.partidas.size();
        }

        /**
         * Este metodo permite crear una partida y agregarla a la lista de partidas
         * de esta clase.
         * @param n int
         * indica el numero de conexión del cliente que quiere inscribirse es decir
         * el puesto que ocupa en la lista de conexiones del servidor.
         * Rango: desde 0 hasta 200 conexiones posibles al servidor de maquinas cliente.
         *
         */
        public void crearPartidas(int n){
            for(int i=0;i<n;i++){
                this.partidas.add(new Partida());
            }
        }

        /**
         * Este metodo permite inscribir a un jugador identificado con el numero
         * de conexion n en la partida i. El numero conexión n indica la posición
         * en las lista de conexiones que tiene el servidor.
         * @param i int
         * indica el numero de la partida donde se quiere inscribir el jugador.
         * Rango: desde 0 hasta 50 partidas para este caso concreto.
         * @param n int
         * indica el numero de conexión del cliente que quiere inscribirse es decir
         * el puesto que ocupa en la lista de conexiones del servidor.
         * Rango: desde 0 hasta 200 conexiones posibles al servidor de maquinas cliente.
         * @return String
         * retorna CONECTADO(s) #jugadores donde #jugadores es el numero de jugadores
         * en la partida i. Si el numero de jugadores en la partida es mayor que 4
         * entonces el sistema informara que la partida esta llena es decir PARTIDA LLENA.
         * 
         */
        public String selectPartidas(int i,int n){
            if(partidas.get(i).getJug()<4){
                partidas.get(i).addJug(this.buscarThread(n));
                return "CONECTADO(s) "+partidas.get(i).getJug();
            }
            else
                return "PARTIDA LLENA";
        }
        /**
         * Este metodo permite adicionar un cliente que esta representado por el
         * socket de java que fue aceptado por el Servidor donde dicho socket
         * representa a un cliente. La clase que representa esta conexión en el
         * sistema se llama ServidorThread.
         * @param Client
         * ServidorThread que representa el socket que fue aceptado de un cliente
         * en el lado del servidor.
         * 
         */
        public void addCliente(ServidorThread Client){
            clientes.add(Client);
        }
        public void actualizarJugPartida(int i){
            partidas.get(i).actualizarJugs();
            if(partidas.get(i).getJug()==4){
                    this.arrancarPartida(i);
            }
        }
        /**
         * Este metodo permite iniciar el hilo de la clase Partida asociado a la
         * posición i de las lista de partidas que contiene esta clase.
         * @param i int
         * representa el numero de la partida cuyo hilo se desea inciar.
         */
        
        public void arrancarPartida(int i){

            
            try {
                Thread.sleep(10);
                System.out.print(".");
                Thread.sleep(10);
                System.out.print(".");
                Thread.sleep(10);
                System.out.print(".");
                Thread.sleep(10);
                System.out.print(".");
            } catch (InterruptedException ex) {
                Logger.getLogger(AdminPartidas.class.getName()).log(Level.SEVERE, null, ex);
            }

            partidas.get(i).jugar();
        }

        /**
         * Este metodo devuelve la conexión o Servidor Thread asociado al numero
         * de conexión n que recibe como parametro. Es posible que el numero de
         * conexión difiera de la posición en la que se encuentra en el arreglo
         * dado que asi como se agregan conexiones tambien se pueden eliminar.
         * Precondición: Se que el cliente siempre lo voy a encontrar en el
         * arreglo sino esta es porque se desconectó.
         * @param n 
         * indica el numero de conexión del cliente que se quiere buscar es decir
         * el puesto que ocupa en la lista de conexiones del servidor.
         * @return ServidorThread
         * Conexión al servidor asociada al numero de conexión n que recibe como
         * parámetro.
         */
        public ServidorThread buscarThread(int n){
            boolean found=false;
            int limSup=this.clientes.size();
            int limInf=0;

            int temp=this.clientes.size()/2;
            if(clientes.get(n).getNumThread()==n)
                return this.clientes.get(n);
            if(temp==0)
                return this.clientes.get(0);  
            else{
                while(!found){
                    if(clientes.get(n).getNumThread()>clientes.get(temp).getNumThread()){
                        limInf=temp;
                    }
                    else if(clientes.get(n).getNumThread()<clientes.get(temp).getNumThread()){
                        limSup=temp; 
                    }
                    else{
                        found=true;
                    }
                    temp=(limSup-limInf)/2;
                }
            }
            return clientes.get(temp);
        }


}
